/* linkit.js
 * By François Leporcq
 * MIT Licensed.
 */
var SVGWorkspace = AbstractWorkspace.extend({
    _className: "SVGWorkspace",
    init: function(container){
        if(container instanceof String || typeof container === "string"){
            container = document.getElementById(container);
        }
        this._container = container;
        this._shapes = new Array();
        this._dragger = new Dragger(this);
        var self = this;
        this._container.onmousemove = function(event){
            self._dragger.move(event);
            self._container.onselectstart = function(){ return false; };
        };
        this._container.onmouseup= function(){
            self._dragger.deselect()
            self._container.onselectstart = function(){ return true; };
        };
    },
    //@Override
    clearAll: function(){
        if ( this.getContainer().hasChildNodes() ){
            while ( this.getContainer().childNodes.length >= 1 ){
                this.getContainer().removeChild( this.getContainer().firstChild );
            }
        }
    },
    //@Override
    clear: function(shape){
        if(shape && shape.element && !shape.isPartOfComposite()){
           this.getContainer().removeChild(shape.element);
        }
    },
    _makeDraggable: function(shape){
        var self = this;
        shape.element.onmousedown= function(event){self._dragger.select(event, shape)};
    },
    _addCssClasses: function(shape, cssClasses){
        if(!shape){
            return;
        }
        if(!cssClasses || cssClasses.length == 0){
            return;
        }

        if(shape instanceof Composite){
            var subShapes = shape.getShapes();
            for(var i=0 ; i < subShapes.length ; i++){
                var cssClassesClone = ObjectUtils.clone(cssClasses);
                this._applyCssClasses(subShapes[i],cssClassesClone);
            }

        }
        shape.element.setAttribute("class", cssClasses.join(" "));
    },
    //@Override
    draw : function(shape){
        if(shape == null){
            return;
        }

        //this._applyCssClasses(shape);

        if(!(shape instanceof AbstractShape)){
            throw new Error("The object to draw must be a child class of AbstractShape");
        }else if(shape instanceof Point){
            this._drawPoint(shape);
        }else if(shape instanceof Line){
            this._drawLine(shape);
        }else if(shape instanceof Polygon || shape instanceof Polyline){
            this._drawPolygon(shape);
        }else if(shape instanceof HTMLContainer){
            this._drawHTMLContainer(shape);
        }else if(shape instanceof AbstractImage){
            this._drawImage(shape);
        }else if(shape instanceof Text){
            this._drawText(shape);
        }else if(shape instanceof Rectangle){
            this._drawRectangle(shape);
        }else if(shape instanceof Circle){
            this._drawCircle(shape);
        }else if(shape instanceof Ellipse){
            this._drawEllipse(shape);
        }else if(shape instanceof BezierCurve){
            this._drawBezierCurve(shape);
        }else if(shape instanceof Composite){
            this._drawComposite(shape);
        }

        this._applyCssClasses(shape);

        if(!shape.isPartOfComposite() && shape.implementationOf(Linkable)){
                this._makeDraggable(shape);
        }

    },
    _drawLine: function(line){
        if(!line.element){
            line.element = this._createSVGElement("line");
            if(!line.isPartOfComposite()){
                this.getContainer().appendChild(line.element);
            }
        }
        var start = line.getStart();
        var end = line.getEnd();
        this._setSVGAttributes(line.element, {
                "x1": start.getX(),
                "y1": start.getY(),
                "x2": end.getX(),
                "y2": end.getY()
            }
        );
    },
    _drawPolygon: function(polygon){
        if(!polygon.element){
            polygon.element = this._createSVGElement(polygon instanceof Polyline ? "polyline" : "polygon");
            if(!polygon.isPartOfComposite()){
                this.getContainer().appendChild(polygon.element);
            }
        }

        var pointsStringBuilder = new Array();
        var points = polygon.getPoints();
        for(var i = 0 ; i < points.length ; i++){
            pointsStringBuilder.push(points[i].getX()+","+points[i].getY());
        }

        this._setSVGAttributes(polygon.element, {"points": pointsStringBuilder.join(" ")});
    },
    _drawPoint: function(point){
        if(!point.element){
            point.element = this._createSVGElement("circle");
            this._setSVGAttributes(point.element, {"r": 3});
            if(!point.isPartOfComposite()){
                this.getContainer().appendChild(point.element);
            }
        }

        this._setSVGAttributes(point.element, {
            "cx": point.getX(),
            "cy": point.getY()
        });

    },
    _drawRectangle: function(rectangle){
        if(!rectangle.element){
            rectangle.element = this._createSVGElement("rect");
            this._setSVGAttributes(rectangle.element, {
                "width": rectangle.getWidth(),
                "height": rectangle.getHeight()
            });
            if(!rectangle.isPartOfComposite()){
                this.getContainer().appendChild(rectangle.element);
            }
        }
        var origin = rectangle.getOrigin();
        this._setSVGAttributes(rectangle.element, {
            "x": origin.getX(),
            "y": origin.getY()
        });
    },
    _drawImage: function(image){
        if(!image.element){
            image.element = this._createSVGElement("image");
            image.element.setAttributeNS("http://www.w3.org/1999/xlink","href",image.getSrc());
            this._setSVGAttributes(image.element, {
                "width": image.getWidth(),
                "height": image.getHeight()
            });
            if(!image.isPartOfComposite()){
                this.getContainer().appendChild(image.element);
            }
        }
        var origin = image.getOrigin();
        this._setSVGAttributes(image.element, {
            "x": origin.getX(),
            "y": origin.getY()
        });
    },
    _drawText: function(text){
        var _LEADING = 1.2;
        if(!text.element){
            text._done = false;
            text.element = this._createSVGElement("text");
            this._setSVGAttributes(text.element,{
                "font-size": Workspace.text.fontSize,
                "font-family": Workspace.text.fontFamily,
                "text-anchor": Workspace.text.anchor
            });

            var words = text.getContent().split("\n");
            var dy = Workspace.text.fontSize * _LEADING;
            for (var i = 0 ; i < words.length;  i++) {
                var tspan = this._createSVGElement("tspan");
                if(i > 0){
                    this._setSVGAttributes(tspan,{
                        "dy": dy
                    });
                }
                tspan.appendChild(document.createTextNode(words[i]));
                text.element.appendChild(tspan);
            }

            if(!text.isPartOfComposite()){
                this.getContainer().appendChild(text.element);
            }
        }

        var origin = text.getOrigin();
        this._setSVGAttributes(text.element, {
            "x": origin.getX(),
            "y": origin.getY()
        });

        var tspans = text.element.getElementsByTagName("tspan");
        for (var i = 0 ; i < tspans.length;  i++) {
            this._setSVGAttributes(tspans[i],{
                "x": origin.getX()
            });
        }
    },
    _drawCircle: function(circle){
        if(!circle.element){
            circle.element = this._createSVGElement("circle");
            this._setSVGAttributes(circle.element, {"r": circle.getRadius()});
            if(!circle.isPartOfComposite()){
                this.getContainer().appendChild(circle.element);
            }
        }
        var origin = circle.getOrigin();
        this._setSVGAttributes(circle.element, {
            "cx": origin.getX(),
            "cy": origin.getY()
        });
    },
    _drawEllipse: function(ellipse){
        if(!ellipse.element){
            ellipse.element = this._createSVGElement("ellipse");
            this._setSVGAttributes(ellipse.element, {
                "rx": ellipse.getXRadius(),
                "ry": ellipse.getYRadius()
            });
            if(!ellipse.isPartOfComposite()){
                this.getContainer().appendChild(ellipse.element);
            }
        }
        var origin = ellipse.getOrigin();
        this._setSVGAttributes(ellipse.element, {
            "cx": origin.getX(),
            "cy": origin.getY()
        });

    },
    _drawBezierCurve: function(curve){
        if(!curve.element){
            curve.element = this._createSVGElement("path");
            if(!curve.isPartOfComposite()){
                this.getContainer().appendChild(curve.element);
            }
        }
        var start = curve.getStart();
        var end = curve.getEnd();
        var first = curve.getFirstControl();
        var second = curve.getSecondControl();

        if(second == null){
            var d = "M " + start.getX() + " " + start.getY() + " Q " + first.getX() + " " + first.getY() + " " + end.getX() + " " + end.getY()
        }else{
            var d = "M  " + start.getX() + " " + start.getY() + " C " + first.getX() + " " + first.getY() + " " + second.getX() + " " + second.getY()+" "+end.getX() + " " + end.getY();
        }

        this._setSVGAttributes(curve.element, {"d": d});
    },
    _drawComposite: function(composite){

        var shapes = composite.getShapes();

        if(!composite.element){
            composite.element = this._createSVGElement("g");
            if(!composite.isPartOfComposite()){
                this.getContainer().appendChild(composite.element);
            }
        }


        for(var i = 0 ; i < shapes.length ; i++){
            this.draw(shapes[i]);

            composite.element.appendChild(shapes[i].element);

            if(shapes[i] instanceof Text && !shapes[i]._done){
                shapes[i]._done = true;
                var firstTspan = shapes[i].element.getElementsByTagName("tspan")[0];
                this._setSVGAttributes(firstTspan,{
                    "dy":shapes[i].getOrigin().getY() - (shapes[i].getComputedY() + shapes[i].getComputedHeight() / 2)
                });
            }
        }



    },
    _drawHTMLContainer: function(container){
        if(!container.element){
            container.element = this._createSVGElement("foreignObject");
            if(!container.isPartOfComposite()){
                this.getContainer().appendChild(container.element);
            }
        }
        this._setSVGAttributes(container.element, {
                "x": container.getOrigin().getX(),
                "y": container.getOrigin().getY(),
                "width": container.getWidth(),
                "height": container.getHeight()
            }
        );
        container.element.appendChild(container.getHTMLNode());
    },
    _createSVGElement:function(type, attributes){
        var element = document.createElementNS("http://www.w3.org/2000/svg" , type);
        this._setSVGAttributes(element, attributes);
        return element;
    },
    _setSVGAttributes:function (element, attributes){
        for(var attribute in attributes){
            var value = attributes[attribute];
            element.setAttributeNS(null, attribute, value);
        }
    }
});
